﻿//-----------------------------------------------------------------------
// <copyright file="DetailedViewItem.cs" company="Microsoft Corporation">
//     Copyright Microsoft Corporation. All Rights Reserved. This code released under the terms of the Microsoft Public License (MS-PL, http://opensource.org/licenses/ms-pl.html.) This is sample code only, do not use in production environments.
// </copyright>
//-----------------------------------------------------------------------
namespace vsarFlightPlan.ViewModels
{
    using System;
    using System.Windows.Input;
    using Utilities;
    using VisualStudioOnlineOData.Models;
    using VisualStudioOnlineOData.Utilities;
    using Windows.System;

    /// <summary>
    ///
    /// </summary>
    internal class DetailedViewItem : ViewModelBase
    {
        private DateTime? _dateLanded;
        private bool _hidden;
        private string _productOwner;
        private string _projectLead;
        private string _ruckMaster;
        private DateTimeOffset _scheduled;
        private string _scheduledStatus;
        private string _state;
        private ProjectStatus _status;
        private string _title;
        private string _version;
        private string OnlineUrl;

        /// <summary>
        /// Initializes a new instance of the <see cref="DetailedViewItem"/> class.
        /// </summary>
        /// <param name="id">The identifier.</param>
        public DetailedViewItem(string id)
        {
            this.Id = id;
            Hidden = SettingUtils.HiddenItemsContainer().Read(this.Id, false);
            Scheduled = DateTimeOffsetTools.Base();
            DateLanded = null;

            ViewOnline = new Command(() =>
                {
                    var __ = Launcher.LaunchUriAsync(new Uri(OnlineUrl));
                });
        }

        public DateTime? DateLanded
        {
            get
            {
                return _dateLanded;
            }
            set
            {
                this.UpdateProperty(ref _dateLanded, value);
                this.RaisePropertyChanged("DateLandedProxy");
                if (value.HasValue)
                {
                    Status = ProjectStatus.Landed;
                }
            }
        }

        public DateTime DateLandedProxy
        {
            get
            {
                return DateLanded.HasValue ? DateLanded.Value : DateTime.Today;
            }
            set
            {
                if (value.Date == DateTime.Today && Status != ProjectStatus.Landed)
                {
                    DateLanded = null;
                }
                else
                {
                    DateLanded = value;
                }
            }
        }

        /// <summary>
        /// Gets or sets the description.
        /// </summary>
        /// <value>
        /// The description.
        /// </value>
        public string Description { get; set; }

        /// <summary>
        /// Gets or sets a value indicating whether [hidden].
        /// </summary>
        /// <value>
        ///   <c>true</c> if [hidden]; otherwise, <c>false</c>.
        /// </value>
        public bool Hidden
        {
            get
            {
                return _hidden;
            }
            set
            {
                this.UpdateProperty(ref _hidden, value);
            }
        }

        /// <summary>
        /// Gets the identifier.
        /// </summary>
        /// <value>
        /// The identifier.
        /// </value>
        public string Id { get; private set; }

        /// <summary>
        /// Gets or sets the original position.
        /// </summary>
        /// <value>
        /// The original position.
        /// </value>
        public int OriginalPosition { get; set; }

        /// <summary>
        /// Gets or sets the product owner.
        /// </summary>
        /// <value>
        /// The product owner.
        /// </value>
        public string ProductOwner
        {
            get
            {
                return _productOwner;
            }
            set
            {
                this.UpdateProperty(ref _productOwner, value);
            }
        }

        /// <summary>
        /// Gets or sets the project lead.
        /// </summary>
        /// <value>
        /// The project lead.
        /// </value>
        public string ProjectLead
        {
            get
            {
                return _projectLead;
            }
            set
            {
                this.UpdateProperty(ref _projectLead, value);
            }
        }

        /// <summary>
        /// Gets or sets the ruck master.
        /// </summary>
        /// <value>
        /// The ruck master.
        /// </value>
        public string RuckMaster
        {
            get
            {
                return _ruckMaster;
            }
            set
            {
                this.UpdateProperty(ref _ruckMaster, value);
            }
        }

        /// <summary>
        /// Gets or sets the scheduled.
        /// </summary>
        /// <value>
        /// The scheduled.
        /// </value>
        public DateTimeOffset Scheduled
        {
            get
            {
                return _scheduled;
            }
            set
            {
                this.UpdateProperty(ref _scheduled, value);
            }
        }

        /// <summary>
        /// Gets or sets the scheduled status.
        /// </summary>
        /// <value>
        /// The scheduled status.
        /// </value>
        public string ScheduledStatus
        {
            get
            {
                return _scheduledStatus;
            }
            set
            {
                this.UpdateProperty(ref _scheduledStatus, value);
            }
        }

        public string State
        {
            get
            {
                return _state;
            }
            set
            {
                this.UpdateProperty(ref _state, value);
            }
        }

        /// <summary>
        /// Gets or sets the status.
        /// </summary>
        /// <value>
        /// The status.
        /// </value>
        public ProjectStatus Status
        {
            get
            {
                return _status;
            }
            set
            {
                this.UpdateProperty(ref _status, value);
                switch (value)
                {
                    case ProjectStatus.Idea:
                        _state = "New";
                        DateLanded = null;
                        this.RaisePropertyChanged("DateLanded");
                        break;

                    case ProjectStatus.InFlight:
                        _state = "In Progress";
                        DateLanded = null;
                        this.RaisePropertyChanged("DateLanded");
                        break;

                    case ProjectStatus.Landed:
                        _state = "Done";
                        break;

                    case ProjectStatus.Cancelled:
                        _state = "Removed";
                        DateLanded = null;
                        this.RaisePropertyChanged("DateLanded");
                        break;

                    case ProjectStatus.Delayed:
                        _state = "In Progress";
                        DateLanded = null;
                        this.RaisePropertyChanged("DateLanded");
                        break;

                    default:
                        DateLanded = null;
                        this.RaisePropertyChanged("DateLanded");
                        break;
                }
                this.RaisePropertyChanged("State");
                this.RaisePropertyChanged("StatusString");
            }
        }

        /// <summary>
        /// Gets or sets the status string.
        /// </summary>
        /// <value>
        /// The status string.
        /// </value>
        public string StatusString
        {
            get
            {
                return _status.ToString();
            }
            set
            {
                this.Status = (ProjectStatus)Enum.Parse(typeof(ProjectStatus), value);
            }
        }

        /// <summary>
        /// Gets or sets the title.
        /// </summary>
        /// <value>
        /// The title.
        /// </value>
        public string Title
        {
            get
            {
                return _title;
            }
            set
            {
                this.UpdateProperty(ref _title, value);
            }
        }

        /// <summary>
        /// Gets or sets the version.
        /// </summary>
        /// <value>
        /// The version.
        /// </value>
        public string Version
        {
            get
            {
                return _version;
            }
            set
            {
                this.UpdateProperty(ref _version, value);
            }
        }

        /// <summary>
        /// Gets or sets the view online.
        /// </summary>
        /// <value>
        /// The view online.
        /// </value>
        public ICommand ViewOnline { get; set; }

        /// <summary>
        /// Detaileds the view item.
        /// </summary>
        /// <param name="item">The item.</param>
        /// <returns></returns>
        public static implicit operator DetailedViewItem(WorkItem item)
        {
            return new DetailedViewItem(item.Id)
                    {
                        Title = item.Title,
                        State = item.State,
                        RuckMaster = item.RuckMaster,
                        ProductOwner = item.ProductOwner,
                        ProjectLead = item.ProjectLead,
                        Version = item.Version,
                        Status = item.Status.ToProjectStatus(),
                        Scheduled = item.Scheduled,
                        DateLanded = item.DateLanded,
                        ScheduledStatus = item.ScheduledStatus,
                        Description = item.Description,
                        OnlineUrl = item.WebEditorUrl,
                        OriginalPosition = item.OriginalPosition
                    };
        }

        /// <summary>
        /// Works the item.
        /// </summary>
        /// <param name="item">The item.</param>
        /// <returns></returns>
        public static implicit operator WorkItem(DetailedViewItem item)
        {
            return new WorkItem()
            {
                Title = item.Title,
                State = item.State,
                RuckMaster = item.RuckMaster,
                ProductOwner = item.ProductOwner,
                ProjectLead = item.ProjectLead,
                Version = item.Version,
                Status = item.Status.ToString(),
                Scheduled = item.Scheduled,
                DateLanded = item.DateLanded,
                ScheduledStatus = item.ScheduledStatus,
                Description = item.Description,
                OriginalPosition = item.OriginalPosition
            };
        }

        /// <summary>
        /// Updates from.
        /// </summary>
        /// <param name="other">The other.</param>
        public void UpdateFrom(DetailedViewItem other)
        {
            this.Title = other.Title;
            this.State = other.State;
            this.Id = other.Id;
            this.RuckMaster = other.RuckMaster;
            this.ProductOwner = other.ProductOwner;
            this.ProjectLead = other.ProjectLead;
            this.Version = other.Version;
            this.Status = other.Status;
            this.Scheduled = other.Scheduled;
            this.DateLanded = other.DateLanded;
            this.ScheduledStatus = other.ScheduledStatus;
            this.Description = other.Description;
        }
    }
}